/*
 * ----------------------------------------------------------------------------
 *  FECHA      HORA   NOMBRE           COMENTARIO     			     
 * ----------------------------------------------------------------------------
 *  08/05/08   17:14  SERGIO Y JAVI    Creación de interface
 *  09/05/08   19:05  DAVID            Creación de algunos metodos
 *  14/05/08   20:00  JAVI             CalculaTemps()
 *  15/05/08   11:40  ALEX             Añadidas notas de programación y el 
 *                                     metodo calculaDistanciaAresta con su
 *                                     javadoc y notas.
 *  21/05/08   19:56  ALEX             Implementación de la clase
 *  30/05/08   00:06  ALEX             Implementación de los metodos SET
 *  2/06/08    17:04  JAVI             Extends Persistent
 */
package net.ieslaferreria.infoCiutat;



import org.garret.perst.IInputStream;
import org.garret.perst.IOutputStream;
import org.garret.perst.Persistent;
import org.garret.perst.Storage;

/**
 * Implementació de la interficie Aresta
 *
 * @author Alex, Javi, David y Sergio
 */
 public class ArestaImpl extends Persistent implements Aresta{

    /*
     * Variable que guarda el codi identificatiu de l'aresta.
     */    
    private int codi;
    /*
     * Variable que guarda el nom de l'aresta.
     */
    private String nom;
    /*
     * Variable que guarda el punt on s'inicia l'aresta.
     */
    private Punt puntInici;
    /*
     * Variable que guarda el punt on acaba l'aresta.
     */
    private Punt puntFinal;
    /*
     * Variable que guarda la distancia entre els dos punts de l'aresta expressada en centimetres.
     */
    private int distancia = 0;
    /*
     * Variable que guarda el temps que es tarda en recorrer l'aresta.
     */
    private int temps;
    /*
     * Variable que guarda el numero de porta en la que s'inicia l'aresta.
     */
    private int numeroInici;
    /*
     * Variable que guarda el numero de porta en la que acaba l'aresta.
     */
    private int numeroFi;
    /*
     * Variable que guarda true si l'aresta es de doble sentit i false si no ho
     * es.
     */
    private boolean dobleSentit;

     public ArestaImpl(){}
     
     public ArestaImpl(Storage db){
         super(db);
     }
    
    public void writeObject(IOutputStream out) { 
        out.writeInt(codi);
        out.writeString(nom);
        out.writeObject((PuntImpl) puntInici);
        out.writeObject((PuntImpl) puntFinal);
        out.writeInt(distancia);
        out.writeInt(temps);
        out.writeInt(numeroInici);
        out.writeInt(numeroFi);
        out.writeBoolean(dobleSentit);
        
     }
    
    public void readObject(IInputStream in) { 
        codi = in.readInt();
        nom = in.readString();
        puntInici = (Punt) in.readObject();
        puntFinal = (Punt) in.readObject();
        distancia = in.readInt();       
        temps = in.readInt();
        numeroInici = in.readInt();
        numeroFi = in.readInt();
        dobleSentit = in.readBoolean();
        
   
    
    }
    public int getCodi() {
        return this.codi;
    }

    public String getNom() {
        return this.nom;
    }

    public int getTemps() {
        return this.temps;
    }

    public Punt getPuntInici() {
        return this.puntInici;
    }

    public Punt getPuntFinal() {
        return this.puntFinal;
    }

    public int getDistanciaPorta(int numero) {
        return numero*(this.getDistancia()/(this.numeroFi - this.numeroInici));
    }

    public int getDistancia() {
        if(this.distancia == 0){
            this.calculaDistanciaAresta();
        }
        return this.distancia;
    }

    public boolean hiHaTransbord() {
        boolean ret = false;
        if(this.getPuntFinal().getLinia() != this.getPuntInici().getLinia()){
            ret = true;
        }
        return ret;
    }

    /**
    * Calcula el temps que es tarda en recorrer l'aresta.
    * 
    * @return int
    */
    /*
    * Comprovem si hi ha transbord (canvi de xarxa) i si la resposta es
    * no. Agafa la distancia de l'aresta i la velocitat mitja de la xarxa i
    * calcula el temps que es tarda en recorrer.
    *
    * Excepció: La distancia pot no estar calculada. En aquest cas 
    * executarem el metode calculaDistanciaAresta i continuarem amb el
    * calcul del temps.
    *
    * Excepció: En el cas que els dos punts no pertanyin a la mateixa
    * xarxa (canvi de xarxa) la velocitat serà la de la xarxa de carrers
    * ja que es la velocitat a peu personalitzable.
    */
    private int calculaTemps() {
        int ret = 0;
        int vel;
        XarxaManager xarxes = new XarxaManagerImpl(InfoCiutat.db);
        if (!this.hiHaTransbord()){
            vel = xarxes.getXarxa(this.getPuntFinal().getCodiXarxa()).getVelocitat();
            ret = (this.getDistancia()/vel);
        } else {
            vel = xarxes.getXarxa(xarxes.CODI_XARXA_CARRERS).getVelocitat();
            ret = (this.getDistancia()/vel);
        }
        return ret;
    }
	
    /**
    * Calcula la distancia entre els dos punts de l'aresta.
    * 
    * @return int
    */
    /*
    * Agafa les coordenades dels dos punts i executa calculaDistancia
    * amb les coordenades dels dos punts.
    * x2 y y2 tindran que ser majors que x1 y y1.
    */
    private int calculaDistanciaAresta() {
        int x1 = this.getPuntInici().getCoordenadaX();
        int y1 = this.getPuntInici().getCoordenadaY();
        int x2 = this.getPuntFinal().getCoordenadaX();
        int y2 = this.getPuntFinal().getCoordenadaY();
        return Math.calculaDistancia(x1, x2, y1, y2);
    }
    
    public int getNumeroInici(){
        int ret = 0;
        if(!this.hiHaTransbord() && this.getPuntInici().
                            getCodiXarxa() == XarxaManager.CODI_XARXA_CARRERS){
        ret = this.numeroInici;
        }
        return ret;
    }
    
    public int getNumeroFinal(){
        int ret = 0;
        if(!this.hiHaTransbord() && this.getPuntInici().
                            getCodiXarxa() == XarxaManager.CODI_XARXA_CARRERS){
        ret = this.numeroFi;
        }
        return ret;
    }

    public boolean esDeDobleSentit() {
        return this.dobleSentit;
    }

    public boolean hiHaCanviDeXarxa() {
        boolean ret = false;
        if(this.getPuntFinal().getCodiXarxa() != this.getPuntInici().getCodiXarxa()){
            ret = false;
        }
        return ret;
    }

    public void setCodi(int codi) {
        this.codi = codi;
    }

    public void setNom(String nom) {
        this.nom = nom;
    }

    public void setTemps(int temps) {
        this.temps = temps;
    }

    public void setPuntInici(Punt puntInici) {
        this.puntInici = puntInici;
    }

    public void setPuntFinal(Punt puntFinal) {
        this.puntFinal = puntFinal;
    }

    public void setDistancia(int distancia) {
        this.distancia = distancia;
    }

    public void setNumeroInici(int numInici) {
        this.numeroInici = numInici;
    }

    public void setNumeroFinal(int numeroFinal) {
        this.numeroFi = numeroFinal;
    }

    public void setDobleSentit(boolean esDobleSentit) {
        this.dobleSentit = esDobleSentit;
    }
    
}
